const { json2yml } = require('./json2yml');
const safeEval = require('safe-eval');
const Document = require('./document');
class Comment {
  constructor(ast) {
    this.ast = ast;
    this.document = new Document();
  }
  get request() {
    if (!this.isEmpty) {
      const requestTag = this.ast.tags.find(_ => _.tag === 'request');
      return (requestTag.description || '').split(/,/).map(_ => this.eval(_.trim()));

    }
  }
  get tags() {
    const tags = [];
    if (!this.isEmpty) {
      const _tags = this.ast.tags.find(_ => _.tag === 'tags');
      if (_tags) {
        const desc = this.eval(_tags.description);
        tags.push(...desc);
      }
    }
    return tags;
  }
  get params() {
    const params = [];
    if (!this.isEmpty) {
      const paramsTag = this.ast.tags.filter(_ => _.tag === 'param');
      for (const paramStr of paramsTag) {
        const param = this.eval(paramStr.description);
        params.push({
          name: param.name,
          in: 'path',
          required: param.required ?? true,
          schema: {
            type: param.type ?? 'string'
          }
        });
      }
    }
    return params;
  }
  get querys() {
    const querys = [];
    if (!this.isEmpty) {
      const queryTag = this.ast.tags.filter(_ => _.tag === 'query');
      for (const queryStr of queryTag) {
        const query = this.eval(queryStr.description);
        querys.push({
          name: query.name,
          in: 'query',
          required: query.required ?? true,
          schema: {
            type: query.type ?? 'string'
          }
        });
      }
    }
    return querys;
  }
  get body() {
    if (!this.isEmpty) {
      const bodyTag = this.ast.tags.find(_ => _.tag === 'body');
      if (!bodyTag) {
        return undefined;
      }
      const desc = bodyTag.description;
      return this.eval(desc);
    }
  }
  get summary() {
    if (!this.isEmpty) {
      const summary = this.ast.tags.find(_ => _.tag === 'summary');
      if (!summary) {
        return undefined;
      }
      const desc = summary.description;
      return this.eval(desc);
    }
  }
  get description() {
    if (!this.isEmpty) {
      const descriptionTag = this.ast.tags.find(_ => _.tag === 'description');
      if (!descriptionTag) {
        return undefined;
      }
      const desc = descriptionTag.description;
      return this.eval(desc);
    }
  }
  get responses() {
    const responses = [];
    if (!this.isEmpty) {
      const responseTags = this.ast.tags.filter(_ => _.tag === 'response');
      for (const responseTag of responseTags) {
        const desc = responseTag.description.split(/,/).map(_ => this.eval(_));
        responses.push(desc);
      }
    }
    return responses;
  }
  get isEmpty() {
    if (this.ast === undefined) {
      return true;
    }
    const requestTag = this.ast.tags.find(_ => _.tag === 'request');
    return !(requestTag && requestTag.description);
  }
  eval(desc) {
    if (!desc) {
      return undefined;
    }
    const content = safeEval(desc);
    return content;
  }
  createDocument() {
    if (!this.ast) {
      return;
    }
    this.document.summary = this.summary;
    this.document.description = this.description;
    if (this.request) {
      this.document.method = this.request[0];
      this.document.path = this.request[1];
    }
    this.document.requestBody = this.body;
    for (const param of this.params) {
      this.document.addParameters(param);
    }
    for(const query of this.querys) {
      this.document.addParameters(query);
    }
    for (const tag of this.tags) {
      this.document.addTag(tag);
    }
    for (const [message, code] of this.responses) {
      this.document.addResponse(message, code);
    }
  }
  toYml() {
    this.createDocument();
    const json = this.document.toJson();
    const ymal = json2yml(json);
    return ymal;
  }
}

module.exports = Comment;